<?php

namespace app\company\controller;

use app\common\controller\CompanyController;
use app\common\exception\BaseException;
use app\common\model\CompanyWarehouse;
use app\common\model\DealerGoodsSpec;
use app\common\model\Driver;
use app\common\service\annotation\ControllerAnnotation;
use app\common\service\annotation\NodeAnnotation;
use app\company\model\CompanyOrder;
use app\company\model\CompanyPickOrder;
use app\company\model\CompanyPickOrderDetail;
use app\company\model\CompanyTransferOrder;
use app\common\model\DealerGoods;
use app\company\model\CompanyWarehouseGoods;
use app\Request;
use jianyan\excel\Excel;
use think\App;
use think\db\exception\DbException;
use think\response\Json;
use app\common\model\Salesman as SalesmanModel;
use app\common\model\Dealer as DealerModel;
use app\company\model\CompanyTransferOrderDetail;
use app\common\enum\order\OrderStatus;

/**
 * @ControllerAnnotation(title="调拨单")
 */
class TransferOrder extends CompanyController
{
    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->model           = new CompanyTransferOrder();
        $this->joinAddTable    = 'detail';
        $this->joinUpdateTable = 'detail';
        $this->joinTable       = 'detail,audit,apply';
        $this->joinDelTable    = 'detail';
        $this->each            = true;
        $this->defaultTemplate = [
                'dealer_name',
                'order_no',
                'create_time',
                'start_warehouse_name',
                'end_warehouse_name',
                'transfer_mode',
                'apply_user_name',
                'goods_name',
                'code69',
                'unit_type',
                'transfer_num',
                'order_remark',
                'detail_remark'
        ];
        $this->importHeader    = [
                '*经销商',
                '*调拨编号',
                '*调拨日期',
                '*调出仓库',
                '*调入仓库',
                '*调拨方式(1司机配送,2货主自提)',
                '*申请人',
                '*商品名称',
                '*商品条码',
                '*单位类型(1小单位,2大单位,3中单位)',
                '*调拨数量',
                '整单备注',
                '明细备注'
        ];
        $this->fileName        = '调拨单导入模版';
    }

    /**
     * @NodeAnnotation (title="列表")
     * @throws DbException
     */
    public function list(): Json
    {
        // 组合查询参数
        list($limit, $where) = $this->buildSearchParams();
        // 获取列表数据
        $sql  = $this->model->where($this->defaultWhere);
        $list = $sql->where($where)
                    ->order($this->sort)
                    ->paginate($limit);
        if ($this->each) $list = $this->each($list);
        return $this->success($list);
    }

    /**
     * @NodeAnnotation (title="调拨出库单")
     * @throws DbException
     */
    public function outList()
    {
        // 组合查询参数
        list($limit, $where) = $this->buildSearchParams();
        // 获取列表数据
        $sql = $this->model->where($this->defaultWhere)
                           ->where('check_status', '<>', 1)
                           ->whereIn('transfer_type', [1, 3])
                           ->where($where)
                           ->order($this->sort);

        $list = $sql->paginate($limit);
        if ($this->each) $list = $this->each($list);
        // 累计统仓费用
        $all_list               = $this->each($sql->select());
        $all_list               = $all_list->toArray();
        $list                   = $list->toArray();
        $list['total_tc_money'] = sprintf("%.2f",array_sum(array_column($all_list, 'tc_rate_total_money')));
        $list['total_tp_money'] = sprintf("%.2f",array_sum(array_column($all_list, 'tp_rate_total_money')));
        $list['total_tx_money'] = sprintf("%.2f",array_sum(array_column($all_list, 'tx_rate_total_money')));
        $list['total_money']    = sprintf("%.2f",array_sum(array_column($all_list, 'rate_total_money')));
        $list['amount']         = sprintf("%.2f",array_sum(array_column($all_list, 'amount')));

        return $this->success($list);
    }

    /**
     * @NodeAnnotation (title="调拨入库库单")
     * @throws DbException
     */
    public function inList(): Json
    {
        // 组合查询参数
        list($limit, $where) = $this->buildSearchParams();
        // 获取列表数据
        $list = $this->model->where($this->defaultWhere)
                            ->where('check_status', 2)
                            ->where('transfer_type', 2)
                            ->where($where)
                            ->order($this->sort)
                            ->paginate($limit);

        if ($this->each) $list = $this->each($list);
        return $this->success($list);
    }

    /**
     * @NodeAnnotation (title="调拨入库签收")
     * @throws DbException
     */
    public function sign(Request $request): Json
    {
        $post = $request->post();
        $row  = $this->model->where('transfer_type', 2)->find($post['id']);
        if (!$row && $row->sign_status != 1) return $this->error('签收错误，请核对订单');
        try {
            $this->model->transaction(function () use ($row)
            {
                // 更新库存
                $detail = $row->detail()->select()->toArray();
                array_walk($detail, function ($item) use ($row)
                {
                    $goods = (new DealerGoods())->where('id', $item['dealer_goods_id'])->find();
                    $ratio = (new DealerGoodsSpec())->where('id', $item['dealer_goods_spec_id'])
                                                    ->value('ratio');
                    if (!$ratio) throw new BaseException(['message' => '请设置商品的箱规比']);
                    $goods->sales_stock     += $item['transfer_num'] * $ratio;
                    $goods->warehouse_stock += $item['transfer_num'] * $ratio;
                    $goods->save();
                    // 处理移动仓商品库存
                    $warehouseInfo = (new CompanyWarehouseGoods())->where('warehouse_id', $row->start_warehouse_id)
                                                                  ->where('dealer_goods_id', $item['dealer_goods_id'])
                                                                  ->find();
                    if ($item['transfer_num'] * $ratio == $warehouseInfo->stock) {
                        $warehouseInfo->delete(true);
                    } else {
                        $warehouseInfo->stock -= $item['transfer_num'] * $ratio;
                        $warehouseInfo->save();
                    }
                });
                $row->save(['sign_status' => 2]);
            });
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
        return $this->success();
    }

    public function each($list)
    {

        foreach ($list as $lk => &$item) {
            $item->startW        = $item->startW()->find();
            $item->endW          = $item->endW()->find();
            $tc_rate_total_money = 0;
            $tp_rate_total_money = 0;
            $tx_rate_total_money = 0;
            $item->detail        = $item->detail()->select();
            foreach ($item->detail as $vo) {
                $vo->goods           = $vo->goods()->withTrashed()->find();
                $vo->spec            = $vo->spec()->withTrashed()->find();
                // 商品当前售价
                $money               = $vo->spec->sale_price;
                $vo->amount  = $total_price = bcmul($vo->transfer_num, $money);
                $tc_rate_money       = $item->dealer()->withTrashed()->value('tc_rate') == 0 ? 0 : bcmul($total_price, $item->dealer()->withTrashed()->value('tc_rate') / 100,2);
                $tp_rate_money = 0;
                $tx_rate_money = 0;
                if(in_array($item->transfer_type,[1,3]) && $item->transfer_mode == 1) $tp_rate_money = $item->dealer()->withTrashed()->value('tp_rate') == 0 ? 0 : bcmul($total_price, $item->dealer()->withTrashed()->value('tp_rate') / 100,2);
                $tc_rate_total_money += $tc_rate_money;
                $tp_rate_total_money += $tp_rate_money;
                $tx_rate_total_money += $tx_rate_money;

            }

            $item->tc_rate_total_money = round($tc_rate_total_money, 2);
            $item->tp_rate_total_money = round($tp_rate_total_money, 2);
            $item->tx_rate_total_money = round($tx_rate_total_money, 2);
            $item->rate_total_money    = round($tc_rate_total_money + $tp_rate_total_money + $tx_rate_total_money,2);

            $item->amount = round(array_sum(array_column($item->detail->toArray(), 'amount')), 2);
            $item->audit  = $item->audit()->find();
            $item->apply  = $item->apply()->find();
            $item->dealer = $item->dealer()->find();

            //访单回库 申请人显示司机名称
            if ($item->transfer_type == 4) {
                $item->apply_name_new = (new Driver())->where('id',$item->apply_user_id)->value('name');
            }

        }

        return $list;

    }

    /**
     * @NodeAnnotation (title="新增")
     * @throws BaseException
     */
    public function add(Request $request): Json
    {
        $this->checkPost();
        $post = $request->post();
        $this->sceneValidate($post, 'add');
        $post['company_id'] = $this->companyId;
        $rule               = [
                'start_warehouse_id|调出仓库' => 'require',
                'dealer_id|经销商'            => 'require',
//                'end_warehouse_id|调入仓库'   => 'require',
                //                'transfer_type|调拨类型'      => 'require',
                'transfer_mode|调拨方式'      => 'require',
                'detail|调拨明细'             => 'require'
        ];
        $this->validate($post, $rule);
        // 判断仓库类型
        if($post['transfer_type'] !=3){
            $startW = (new CompanyWarehouse())->where('id', $post['start_warehouse_id'])->value('type');
            $endW   = (new CompanyWarehouse())->where('id', $post['end_warehouse_id'])->value('type');
            if ($startW == 1 && $endW == 2) {
                $post['transfer_type'] = 1;
            }
            if ($startW == 2 && $endW == 1) {
                $post['transfer_type'] = 2;
            }
            if ($startW == $endW) {
                return $this->error('暂不支持同类型仓库调拨');
            }
        }

        try {
            $this->model->transaction(function () use ($post)
            {
                $detail              = json_decode($post['detail'], true);
                $post['order_no']    = generateOrderNo('DB');
                $post['product_num'] = array_sum(array_column($detail, 'transfer_num'));
                $post['cate_num']    = count(array_unique(array_column($detail, 'dealer_goods_id')));
                $this->model->save($post);
                if ($post['transfer_type'] == 1 || $post['transfer_type'] == 3) {
                    // 判断库存
                    array_walk($detail, function ($item)
                    {
                        $goods = (new DealerGoods())->where('id', $item['dealer_goods_id'])
                                                    ->find();
                        $ratio = (new DealerGoodsSpec())->where('id', $item['dealer_goods_spec_id'])
                                                        ->value('ratio');
                        $stock = $item['transfer_num'] * $ratio;
                        if ($ratio && $stock > $goods->sales_stock) throw new BaseException(['message' => '商品【' . $goods->name . '】库存不足']);
                        // 扣减售卖库存
                        $goods->dec('sales_stock', $item['transfer_num'] * $ratio)->save();
                    });
                }
                // 如果有需要添加的关联表数据
                if ($this->joinAddTable) $this->joinAddTable($post);
            });
        } catch (\Exception $e) {
            return $this->error('新增失败:' . $e->getMessage());
        }
        return $this->success('新增成功');
    }

    /**
     * @NodeAnnotation (title="修改")
     * @throws BaseException
     */
    public function edit(Request $request): Json
    {
        $this->checkPost();
        $post = $request->post();
        $this->sceneValidate($post, 'add');
        $post['company_id'] = $this->companyId;
        $rule               = [
            'start_warehouse_id|调出仓库' => 'require',
            'dealer_id|经销商'            => 'require',
            'end_warehouse_id|调入仓库'   => 'require',
            'transfer_mode|调拨方式'      => 'require',
            'detail|调拨明细'             => 'require'
        ];
        $this->validate($post, $rule);
        // 判断仓库类型
        $startW = (new CompanyWarehouse())->where('id', $post['start_warehouse_id'])->value('type');
        $endW   = (new CompanyWarehouse())->where('id', $post['end_warehouse_id'])->value('type');
        if ($startW == 1 && $endW == 2) {
            $post['transfer_type'] = 1;
        }
        if ($startW == 2 && $endW == 1) {
            $post['transfer_type'] = 2;
        }
        if ($startW == $endW) {
            return $this->error('暂不支持同类型仓库调拨');
        }
        try {
            $this->model->transaction(function () use ($post) {
                $detail              = json_decode($post['detail'], true);
                $post['order_no']    = generateOrderNo('DB');
                $post['product_num'] = array_sum(array_column($detail, 'transfer_num'));
                $post['cate_num']    = count(array_unique(array_column($detail, 'dealer_goods_id')));
                $row = $this->model->find($post['id']);
                $row->save($post);
                if ($post['transfer_type'] == 1) {
                    // 判断库存
                    array_walk($detail, function ($item, $row) {
                        $goods = (new DealerGoods())->where('id', $item['dealer_goods_id'])
                            ->find();
                        $ratio = (new DealerGoodsSpec())->where('id', $item['dealer_goods_spec_id'])
                            ->value('ratio');
                        $stock = $item['transfer_num'] * $ratio;
                        if ($ratio && $stock > $goods->sales_stock) throw new BaseException(['message' => '商品【' . $goods->name . '】库存不足']);
                        // 扣减售卖库存
                         if( $item['transfer_num']> $row['transfer_num']){
                            $goods->dec('sales_stock',   ($item['transfer_num']- $row['transfer_num']) * $ratio)->save();
                         }else{
                            $goods->inc('sales_stock',   abs($item['transfer_num']- $row['transfer_num']) * $ratio)->save();
                         }
                    });
                }
                // 如果有需要添加的关联表数据
                if ($this->joinUpdateTable) $this->joinUpdateTable($post,$row );
            });
        } catch (\Exception $e) {
            return $this->error('修改失败:' . $e->getMessage());
        }
        return $this->success('修改成功');
    }
    /**
     * @NodeAnnotation (title="审核")
     */
    public function check(Request $request): Json
    {
        $this->checkPost();
        $post = $request->post();
        $row  = $this->model->find($post['id']);
        if (!$row && $row->audit_user_id) return $this->error('该订单已审核');
        try {
            $this->model->transaction(function () use ($row)
            {
                $row->save([
                                   'audit_user_id' => $this->uid,
                                   'check_status'  => 2
                           ]);
                //访单回库，直接回退库存
                if ($row->transfer_type == 4) {
                    $this->stockReturn($row->id);
                }

            });
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
        return $this->success('操作成功');
    }

    /**
     * @NodeAnnotation (title="生成捡货单")
     */
    public function pick(Request $request): Json
    {
        $this->checkPost();
        $post = $request->post();
        $id   = $request->post('id', '');
        if (empty($id)) return $this->error('订单ID不能为空');
        $ids = explode(',', $id);
        try {
            $pickModel = new CompanyPickOrder();
            // 判断是否已经存在捡货单
            array_walk($ids, function ($id)
            {
                $pickDetailModel = new CompanyPickOrderDetail();
                $orderNo         = $this->model->where('id', $id)->value('order_no');
                $pickOrderDetail = $pickDetailModel->where('transfer_order_id', $id)->find();
                if ($pickOrderDetail) throw new \Exception('订单【' . $orderNo . '】已生成捡货单');
            });
            // 过滤订单
            $orderIds = $this->model->where('id', 'in', $id)
                                    ->where('check_status', 2)
                                    ->where('pick_status', 1)
                                    ->where('order_status', 1)
                                    ->column('id');
            if (empty($orderIds)) return $this->error('订单状态不正确，不允许出库');
            // 生成捡货单
            $productNum = $this->model->whereIn('id', $orderIds)->sum('product_num');
            $pickModel->save([
                                     'company_id'         => $this->companyId,
                                     'type'               => 3,
                                     'transfer_order_ids' => implode(',', $orderIds),
                                     'pick_order_no'      => generateOrderNo('PK'),
                                     'order_num'          => count($orderIds),
                                     'pick_num'           => $productNum,
                                     'true_pick_num'      => $productNum
                             ]);
            // 生成分拣单详情表
            $detail = array_map(function ($orderId) use ($pickModel)
            {
                $dealerId = $this->model->where('id', $orderId)->value('dealer_id');
                return [
                        'company_pick_order_id' => $pickModel->id,
                        'transfer_order_id'     => $orderId,
                        'dealer_id'             => $dealerId,
                ];
            }, $orderIds);
            $pickModel->detail()->saveAll($detail);
            // 更新当单状态
            $this->model->whereIn('id', $orderIds)->update(['pick_status' => 2]);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
        return $this->success('操作成功');
    }

    /**
     * @NodeAnnotation (title="删除")
     * @throws BaseException
     */
    public function del(Request $request): Json
    {
        $this->checkPost();
        $post = $request->post();
        $rule = [
                'id' => 'require'
        ];
        $this->validate($post, $rule);
        $ids = explode(',', $post['id']);
        try {
            foreach ($ids as $v) {
                $sql = $this->model;
                if ($this->joinDelTable) {
                    // 关联删除
                    $row = $sql->with(explode(',', $this->joinDelTable))->find($v);
                    if($row->check_status == 3) throw new BaseException(['message'=>'该订单已出库，无法删除']);
                    if ($row) {
                        // 获取详情
                        if ($row->transfer_type == 1 || $row->transfer_type == 3) {
                            // 查询订单详情
                            $detail = $row->detail()->field('dealer_goods_id,dealer_goods_spec_id,transfer_num')
                                          ->select()->toArray();
                            array_walk($detail, function ($item)
                            {
                                $ratio = (new DealerGoodsSpec())->where('id', $item['dealer_goods_spec_id'])
                                                                ->value('ratio');
                                (new DealerGoods())->where('id', $item['dealer_goods_id'])
                                                   ->inc('sales_stock', $item['transfer_num'] * $ratio)
                                                   ->save();
                            });
                        }
                        $row->together(explode(',', $this->joinDelTable))->delete();
                    }
                }
            }
        } catch (\Exception $e) {
            return $this->error('删除失败:' . $e->getMessage());
        }
        return $this->success('删除成功');
    }

    /**
     * @NodeAnnotation(title="取消")
     */
    public function cancel(Request $request): Json
    {
        $this->checkPost();
        $post = $request->post();
        $this->validate($post, ['id' => 'require']);
        $info = $this->model->find($post['id']);
        if (!$info || $info->order_status != 1) return $this->error('无效的订单');
        try {
            $info->order_status = 2;
            // 释放库存
            if ($info->transfer_type == 1) {
                // 查询订单详情
                $detail = $info->detail()->field('dealer_goods_id,dealer_goods_spec_id,transfer_num')
                               ->select()->toArray();
                array_walk($detail, function ($item)
                {
                    $ratio = (new DealerGoodsSpec())->where('id', $item['dealer_goods_spec_id'])
                                                    ->value('ratio');
                    (new DealerGoods())->where('id', $item['dealer_goods_id'])
                                       ->inc('sales_stock', $item['transfer_num'] * $ratio)
                                       ->save();
                });
            }
            $info->save();
        } catch (\Exception $e) {
            return $this->error('取消失败:' . $e->getMessage());
        }
        return $this->success('取消成功');
    }

    /**
     * @NodeAnnotation(title="确认出库")
     */
    public function checkOut(Request $request): Json
    {
        $this->checkPost();
        $post = $request->post();
        $this->validate($post, ['id' => 'require']);
        $info = $this->model->find($post['id']);
//        if (!$info || $info->check_status != 2 || $info->transfer_type != 1 || $info->order_status != 1) return $this->error('无效的订单');
        try {
            // 修改订单状态
            $info->check_status = 3;
            // 扣减仓库库存
            $info->detail()->select()->each(function ($item) use ($info)
            {

                $specInfo = (new DealerGoodsSpec())->where('id', $item->dealer_goods_spec_id)
                                                   ->find();

                (new DealerGoods())->where('id', $item['dealer_goods_id'])
                                   ->dec('warehouse_stock', $item->transfer_num * $specInfo->ratio)
                                   ->save();
                // 新增车销商品信息数据
                $warehouseGoods = CompanyWarehouseGoods::where([
                                                                       'company_id'      => $this->companyId,
                                                                       'dealer_goods_id' => $item->dealer_goods_id,
                                                                       'dealer_id'       => $info->dealer_id,
                                                                       'warehouse_id'    => $info->end_warehouse_id,
                                                               ])->withTrashed()->find() ?: new CompanyWarehouseGoods();

                $warehouseGoods->company_id      = $this->companyId;
                $warehouseGoods->dealer_goods_id = $item->dealer_goods_id;
                $warehouseGoods->dealer_id       = $info->dealer_id;
                $warehouseGoods->warehouse_id    = $info->end_warehouse_id;
                $warehouseGoods->stock           = $item->transfer_num * $specInfo->ratio;
                $warehouseGoods->delete_time     = null;
                $warehouseGoods->save();
            });
            $info->save();
        } catch (\Exception $e) {
            return $this->error('确认出库失败:' . $e->getMessage());
        }
        return $this->success('确认出库成功');
    }

    /**
     * @NodeAnnotation(title="导入")
     */
    public function import(Request $request): Json
    {

        $this->model->startTrans();
        try {
            $this->checkPost();
            $file = $request->file('file');
            if (!$file) return $this->error('请上传文件！');
            // 保存文件到临时目录
            $savePath = $file->move('storage' . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR);
            // 获取文件的完整路径
            $savePath = $savePath->getPathname();
            $data     = Excel::import($savePath, 1, false, 'Xlsx', './storage/temp/excelImg/');
            if (!$data) throw new BaseException(['message' => '文件内容为空！']);
            if (!$this->importHeader) throw new BaseException(['message' => '请联系管理设置文件模版']);
            if (array_filter($data[0]) != $this->importHeader) throw new BaseException(['message' => '文件格式不正确']);
            unset($data[0]);
            $data = array_filter($data);
            array_pop($data);
            $this->dealOrders($data);
            @unlink($savePath);
        } catch (\Exception $e) {
            $this->model->rollback();
            return $this->error('导入失败！' . $e->getMessage());
        }

        return $this->success('导入成功！');
    }

    private function dealOrders(array $data)
    {

        if (empty($data)) throw new BaseException(['message' => '文件内容为空！']);
        $orders   = array_map(function ($vo)
        {
            $fields = $this->defaultTemplate;
            $data   = array_combine($fields, $vo);
            // print_r($data   );
            // return ;
            // 验证表格中的值
            $rule = [
                    'order_no|调拨编号'             => 'require',
                    'create_time|调拨日期'          => 'require',
                    'dealer_name|经销商'            => 'require',
                    'apply_user_name|申请人'        => 'require',
                    'start_warehouse_name|调出仓库' => 'require',
                    'end_warehouse_name|调入仓库'   => 'require',
                    'transfer_mode|调拨方式'        => 'require',
                    'goods_name|商品名称'           => 'require',
                    'code69|商品条码'               => 'require',
                    'transfer_num|调拨数量'         => 'require',
                    'unit_type|单位类型'            => 'require',
            ];
            $this->validate($data, $rule);
            return $data;
        }, $data);
        $orderNos = array_unique(array_column($orders, 'order_no'));

        // print_r( $orderNos);
        // return;
        $i = 0;
        foreach ($orderNos as $orderNo) {
            // 匹配订单
            $filteredArray = array_filter($orders, function ($item) use ($orderNo)
            {
                return $item['order_no'] === $orderNo;
            });
            // 重组
            $orderData = array_values($filteredArray);
            // print_r("循环111");
            // print_r($orderData);

            //// 订单公共信息
            //需要的数据
            // apply_user_id
            // $data1 = $orderData[0];
            // var_dump(strtotime($data1['create_time'])) ;
            return;
            $post                  = [];
            $post['apply_user_id'] = SalesmanModel::where('company_id', $this->companyId)
                                                  ->where('rename', $data1['apply_user_name'])
                                                  ->value('id');
            //dealer_id
            $post['dealer_id'] = DealerModel::where('company_id', $this->companyId)
                                            ->where('name', $data1['dealer_name'] ?? '')
                                            ->value('id');
            //remark
            $post['remark'] = $data1['order_remark'] ?? '';
            //start_warehouse_id
            $warehouse_model            = new CompanyWarehouse();
            $start_warehouse            = $warehouse_model->where('name', $data1['start_warehouse_name'])
                                                          ->field('id,type')->find();
            $post['start_warehouse_id'] = $start_warehouse['id'];
            //end_warehouse_id
            $end_warehouse            = $warehouse_model->where('name', $data1['end_warehouse_name'])->field('id,type')
                                                        ->find();
            $post['end_warehouse_id'] = $end_warehouse['id'];

            if ($start_warehouse['type'] == $end_warehouse['type']) {
                return $this->error('暂不支持同类型仓库调拨');
            }
            //transfer_mode
            if ($end_warehouse['type'] == 2) {
                $post['transfer_type'] = 1;
            } else {
                $post['transfer_type'] = 2;
            }

            //transfer_type
            // if ($data1['transfer_mode'] == '司机配送') {
            //     $post['transfer_mode'] = 1;
            // } else {
            //     $post['transfer_mode'] = 2;
            // }
            $post['transfer_mode'] = $data1['transfer_mode'];
            //调拨日期
            $post['create_time'] = strtotime($data1['create_time']);
            $post['order_no']    = $data1['order_no'];
            $post['company_id']  = $this->companyId;

            $transfer_num_count = 0;
            $cate_arr           = [];
            $detail             = [];

            foreach ($orderData as $k => &$v) {
                //detail
                //dealer_goods_id
                $goods                         = (new DealerGoods())->where('name', $v['goods_name'])
                                                                    ->field('id,name,sales_stock')->find();
                $detail[$k]['dealer_goods_id'] = $goods['id'];

                //dealer_goods_spec_id
                $goods_spec = (new DealerGoodsSpec())->where([['dealer_goods_id', '=', $goods['id']], ['unit_type', '=', $v['unit_type']]])
                                                     ->field('id,ratio')->find();
                //transfer_num
                $detail[$k]['transfer_num'] = $v['transfer_num'];

                //remark
                $detail[$k]['create_time'] = $post['create_time'];

                $detail[$k]['remark'] = $v['detail_remark'] ?? '';

                $detail[$k]['dealer_goods_spec_id'] = $goods_spec['id'];

                $transfer_num_count += $v['transfer_num'];

                array_push($cate_arr, $goods['id']);

                if ($post['transfer_type'] == 1) {
                    // 判断库存
                    $stock = $v['transfer_num'] * $goods_spec['ratio'];
                    if ($stock > $goods->sales_stock) {
                        throw new BaseException([
                                                        'message' => '商品【' . $goods->name . '】库存不足' . $goods->sales_stock,
                                                ]);
                    }
                    // 扣减售卖库存
                    $goods->dec('sales_stock', $v['transfer_num'] * $goods_spec['ratio'])->save();
                }
            };
            $post['product_num'] = $transfer_num_count;
            $post['cate_num']    = count(array_unique($cate_arr));

            // print_r("循环第".$i."次数");
            $i++;
            // print_r($post);

            $this->model->transaction(function () use ($detail, $post)
            {

                // 如果有需要添加的关联表数据
                // print_r($post['order_no']);
                //->fetchSql(true)
                $last_id = $this->model->insertGetId($post);
                foreach ($detail as $dk => &$dv) {
                    $dv['t_oid'] = $last_id;
                };
                // print_r($last_id);
                $transfer_order_detail = new CompanyTransferOrderDetail();
                $transfer_order_detail->insertAll($detail);
                $this->model->commit();
            });
        }
    }

    /**
     * 调拨出库报表
     * @param Request $request
     * @return Json
     */
    public function report(Request $request): Json
    {
        $page        = $request->get('page', 1);
        $limit       = $request->get('limit', 10);
        $start_time  = $request->get('start_time', '');
        $end_time    = $request->get('end_time', '');
        $dealer_name = $request->get('dealer_name', '');
        $goods_name  = $request->get('goods_name', '');

        $sql   = $this->model->alias('t')
                             ->join('company_transfer_order_detail td', 't.id = td.t_oid')
                             ->join('dealer d', 't.dealer_id = d.id')
                             ->join('dealer_goods g', 'td.dealer_goods_id = g.id')
                             ->join('dealer_goods_spec gs', 'td.dealer_goods_spec_id = gs.id')
                             ->join('goods_cate gc', 'g.cate_id = gc.id');
        $where = [];
        if ($start_time) {
            $where[] = ['t.create_time', '>=', $start_time];
        }
        if ($end_time) {
            $where[] = ['t.create_time', '<=', $end_time];
        }
        if ($dealer_name) {
            $where[] = ['d.name', 'like', '%' . $dealer_name . '%'];
        }
        if ($goods_name) {
            $where[] = ['g.name', 'like', '%' . $goods_name . '%'];
        }
        $where[] = ['t.transfer_type', '=', 1];
        $where[] = ['t.transfer_mode', '=', 1];
        $where[] = ['t.check_status', '=', 3];
        $sql     = $sql->where($where)->group('td.dealer_goods_id');
        $list    = $sql->field('g.name as goods_name, gs.name as spec_name, gc.name as cate_name,
        sum(td.transfer_num) as num, sum(td.transfer_num * gs.sale_price) as amount, gs.unit,
        d.name as dealer_name')
                       ->page($page, $limit)
                       ->select();
        $count   = $sql->count();
        return $this->success(['list' => $list, 'count' => $count]);
    }

    private function stockReturn($transfer_order_id)
    {
        $list = (new CompanyTransferOrderDetail())->where('t_oid', $transfer_order_id)->field('dealer_goods_id,dealer_goods_spec_id,transfer_num')->select()->toArray();
        if (!empty($list)) {
            $goodsModel = new DealerGoods();
            $specModel = new DealerGoodsSpec();
            array_map(function ($value) use ($specModel, $goodsModel) {
                $specModel->where('id', $value['dealer_goods_spec_id'])
                    ->inc('stock', $value['transfer_num'])
                    ->save();
                // 计算商品的比例增加至商品的库内库存、售卖库存
                $specInfo = $specModel->where('id', $value['dealer_goods_spec_id'])->withTrashed()->find();
                if (!$specInfo['ratio']) throw new BaseException(['message' => $specInfo['name'] . '--商品规格比例不能为0']);
                if (!$value['transfer_num']) throw new BaseException(['message' => $specInfo['name'] . '--商品数量不能为0']);
                $goodsModel->where('id', $value['dealer_goods_id'])
                    ->inc('sales_stock', $value['transfer_num'] * $specInfo['ratio'])
                    ->inc('warehouse_stock', $value['transfer_num'] * $specInfo['ratio'])->save();
            }, $list);
            //修改订单状态为已完成
            (new CompanyOrder())->save(['order_status' => OrderStatus::FINISH]);
        }
        return true;
    }
}
